package remote

import (
	"apedge/pkg/common"
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"time"
)

type EndPointsAndPolicies struct {
	Module    Module       `json:"module"`
	EndPoints []EndPoint   `json:"endpoints"`
	Policies  InitPolicies `json:"policies"`
}

type Module struct {
	Account    string `json:"account"`
	ModuleName string `json:"moduleName"`
	Desc       string `json:"desc"`
}

type InitPolicies struct {
	Module    string         `json:"module"`
	SysAdmin  []StatementDto `json:"systemAdmin"`
	OrgAdmin  []StatementDto `json:"orgAdmin"`
	Developer []StatementDto `json:"developer"`
}

type EndPoint struct {
	Module       string `form:"module"`
	Desc         string `form:"desc"`
	Resource     string `form:"resource"`
	Action       string `form:"action"`
	HttpMethod   string `form:"httpMethod"`
	HttpEndpoint string `form:"httpEndpoint"`
}

type StatementDto struct {
	Actions   []string `form:"actions"`
	Resources []string `form:"resources"`
	Effect    string   `form:"effect" validate:"oneof=allow deny"`
	Role      string   `form:"role"`
}

func InitEndpointPolicy() error {
	var err error
	var client = &http.Client{
		Timeout: time.Second * 10,
	}

	endpoint := EndPointsAndPolicies{}
	url := "http://iam-backend.default/api/v1/endpoints"

	var ValidationJsonString = "{\"module\":{\"account\":\"apflow\",\"moduleName\":\"apflow\",\"desc\":\"\u63a8\u7406\u4e2d\u5fc3\"},\"endpoints\":[{\"resource\":\"*\",\"action\":\"apflow:node:list\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:detail\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node{nodeId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:create\",\"httpMethod\":\"post\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:delete\",\"httpMethod\":\"delete\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/{nodeId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:nodeType\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/nodeType\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:nodeArchType\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/nodeArchType\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:certificate\",\"httpMethod\":\"post\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/certificate/{nodeId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:scripts\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/scripts\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:offline\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/offline\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:node:download\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/node/download/{nodeId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:nodeGroup:list\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/nodeGroup\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:nodeGroup:detail\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/nodeGroup/{id}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:nodeGroup:create\",\"httpMethod\":\"post\",\"httpEndpoint\":\"/apedge/api/v1/apedge/nodeGroup\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:nodeGroup:delete\",\"httpMethod\":\"delete\",\"httpEndpoint\":\"/apedge/api/v1/apedge/nodeGroup/{id}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:list\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:detail\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/{serviceId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:create\",\"httpMethod\":\"post\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:delete\",\"httpMethod\":\"delete\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/{serviceId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:serviceNodeList\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/serviceNode\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:edit\",\"httpMethod\":\"patch\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/serviceNode\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:serviceNodeDelete\",\"httpMethod\":\"delete\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/serviceNode/{serviceNodeId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:edgeinfer:predict_info\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/apedge/api/v1/apedge/inference/predict_info/{serviceId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:list\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:detail\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:create\",\"httpMethod\":\"post\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:edit\",\"httpMethod\":\"put\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:delete\",\"httpMethod\":\"delete\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:patch\",\"httpMethod\":\"patch\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:log\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/log/download/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:predict_info\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/predict_info/{taskId}\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:apscList\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/list\",\"module\":\"apflow\",\"desc\":\"1\"},{\"resource\":\"*\",\"action\":\"apflow:task:apscinfo\",\"httpMethod\":\"get\",\"httpEndpoint\":\"/bffapflow/api/v1/bffapflow/task/static_info\",\"module\":\"apflow\",\"desc\":\"1\"}],\"policies\":{\"module\":\"apflow\",\"systemAdmin\":[{\"actions\":[\"apflow:task:*\",\"apflow:node:*\",\"apflow:nodeGroup:*\",\"apflow:edgeinfer:*\"],\"effect\":\"allow\"}],\"orgAdmin\":[{\"actions\":[\"apflow:task:*\",\"apflow:node:*\",\"apflow:nodeGroup:*\",\"apflow:edgeinfer:*\"],\"effect\":\"allow\"}],\"developer\":[{\"actions\":[\"apflow:task:*\",\"apflow:node:*\",\"apflow:nodeGroup:*\",\"apflow:edgeinfer:*\"],\"effect\":\"allow\"}],\"annotator\":[{\"actions\":[\"apflow:task:*\",\"apflow:node:*\",\"apflow:nodeGroup:*\",\"apflow:edgeinfer:*\"],\"effect\":\"allow\"}],\"public\":[{\"actions\":[\"apflow:task:*\",\"apflow:node:*\",\"apflow:nodeGroup:*\",\"apflow:edgeinfer:*\"],\"effect\":\"allow\"}]}}"

	validationJsonByte := []byte(ValidationJsonString)
	err = json.Unmarshal(validationJsonByte, &endpoint)
	if err != nil {
		return err
	}
	jsonValue, err := json.Marshal(endpoint)
	if err != nil {
		return err
	}
	req, err := http.NewRequest("POST", url, bytes.NewReader(jsonValue))
	if err != nil {
		return err
	}

	req.Header.Add("Content-Type", "application/json")
	// check for endpoint registration response
	resp, err := client.Do(req)
	if err != nil || resp.StatusCode != http.StatusOK {
		logger.Errorln("--------------", resp.StatusCode)
		logger.Errorf("InitEndpointPolicy 1: %v", err)
		return common.ErrInitEndpointPolicy
	}

	bodys, err := ioutil.ReadAll(resp.Body)
	if err != nil || resp.StatusCode != http.StatusOK {
		logger.Errorln("--------------", resp.StatusCode)
		logger.Errorf("InitEndpointPolicy 2: %v", err)
		return common.ErrInitEndpointPolicy
	}

	logger.Info("EndPoint registration response: " + string(bodys))
	return nil
}
